﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Zocono.Infrastructure.Common;
using Zocono.WCS.Domain.DomainRepository;
using Zocono.WCS.Domain.EntityInfo;
using Zocono.WCS.Domain.GlobalClass;
using Zocono.WCS.Domain.LogDomain;
using Zocono.WCS.Infrastructure.ApllicationDto.Enums;
using Zocono.WCS.Infrastructure.ApllicationDto.WCSTaskDto;
using Zocono.WCS.WMSApiDomain.WebApi;

namespace Zocono.WCS.Domain.WcsGetWmsJobDomain
{
    public class WcsGetWmsJobService : IWcsGetWmsJobService
    {
        private readonly IWorkTaskInfoRepository _workTaskInfoRepository;
        private readonly IRouteInfoRepository _RouteInfoRepository;
        private readonly IRouteDetailInfoRepository _RouteDetailInfoRepository;
        private readonly ILogUtil _LogUtil;
        private readonly ISnowflake _Snowflake;

        private IInterfaceLogInfoService _IIterfaceLogInfoService;

        public WcsGetWmsJobService(IWorkTaskInfoRepository workTaskInfoRepository,
            IRouteInfoRepository routeInfoRepository,
            IRouteDetailInfoRepository routeDetailInfoRepository,
            ILogUtil logUtil,
            ISnowflake snowflake, IInterfaceLogInfoService _iterfaceLogInfoService)
        {
            _workTaskInfoRepository = workTaskInfoRepository;
            _RouteInfoRepository = routeInfoRepository;
            _RouteDetailInfoRepository = routeDetailInfoRepository;
            _LogUtil = logUtil;
            _Snowflake = snowflake;
            _IIterfaceLogInfoService = _iterfaceLogInfoService;
        }
        //后期可加异步锁
        private static readonly object _lockTask = new object();
        public async Task WCSGetWMSInitialWorkTaskAsync()
        {
            _LogUtil.Info("获取WMS任务开始>>>>>>>>>>>>>");
            //await lock_task.WaitAsync();
            InterfaceLogInfo interfaceLogInfo = new()
            {
                InterfacePara = $"WMS下发初始作业",
                ActionName = "WCSGetWMSInitialWorkTaskAsync",
                StartTime = DateTime.Now,
                InterfaceUrl = Parameters.WCSGetWMSInitialWorkTask,
                Description = $"类型：WMS下发初始作业"
            };

            //WMS下发初始作业
            var starttime = DateTime.Now.ToString("G");

            try
            {
                var wmstasks = await WCSMessageWithWMSApi.WCSGetWMSInitialWorkTaskAsync(_IIterfaceLogInfoService);
                if (wmstasks != null && wmstasks.Count > 0)
                {
                    interfaceLogInfo.InterfaceResult = JsonConvert.SerializeObject(wmstasks);
                    interfaceLogInfo.EndTime = DateTime.Now;
                    interfaceLogInfo.IsSuccess = true;
                    var resinfo = await _IIterfaceLogInfoService.AddInterfaceLogAsync(interfaceLogInfo);
                    var routeInfos = await _RouteInfoRepository.GetListAsync();
                    var routrdetailinfos = await _RouteDetailInfoRepository.GetListAsync();
                    try
                    {
                        foreach (var temp in wmstasks)
                        {

                            #region OLD
                            ////LogWriter.WriteLogWMSApiJson("向WMS获取出库，移库等自动下发任务："+Newtonsoft.Json.JsonConvert.SerializeObject(temp));
                            //var check = await _workTaskInfoRepository.CountAsync(it => it.WmsTaskCode == temp.TaskCode && (it.TaskState == EnumTaskState.Executing || it.TaskState == EnumTaskState.Initial));
                            //if (check > 0)
                            //{
                            //    //存在任务则上报给wms此任务已下发
                            //    bool flag = await WCSMessageWithWMSApi.WCSUpdateWMStaskStateAndProcessTaskStateAsync(temp.TaskCode, 1, null);
                            //    interfaceLogInfo.Description = $"WMS 作业号{temp.TaskCode} 已经存在";
                            //    await _IIterfaceLogInfoService.AddInterfaceLogAsync(interfaceLogInfo);
                            //    continue;
                            //    //throw new Exception($"WMS 作业号{temp.TaskCode} 已经存在");
                            //}
                            #endregion

                            #region NEW
                            var taskchecklist = await _workTaskInfoRepository.AsSugarClient().Queryable<WorkTaskInfo>()
                                            .Where(it => it.WmsTaskCode == temp.TaskCode && (it.TaskState == EnumTaskState.Executing || it.TaskState == EnumTaskState.Initial))
                                            .OrderBy(it => it.SaveTime, SqlSugar.OrderByType.Desc)
                                            .ToListAsync();
                            if (taskchecklist.Count > 0)
                            {
                                var taskcheck = taskchecklist.Find(it => it.WmsFromPosition == temp.StartPosition && it.WmsToPosition == temp.EndPosition);
                                if (taskcheck != null)
                                {
                                    taskchecklist.Remove(taskcheck);
                                    if (taskchecklist.Count > 0)
                                    {
                                        foreach (var ts in taskchecklist)
                                        {
                                            ts.TaskState = EnumTaskState.ManualFinish;
                                            ts.UpdateTime = DateTime.Now;
                                        }
                                        await _workTaskInfoRepository.AsSugarClient().Updateable(taskchecklist).ExecuteCommandAsync();
                                    }

                                    await WCSMessageWithWMSApi.WCSUpdateWMStaskStateAndProcessTaskStateAsync(temp.TaskCode, 1, 0);
                                    interfaceLogInfo.Description = $"WMS 作业号{temp.TaskCode} 已经存在";
                                    try
                                    {
                                        await _IIterfaceLogInfoService.AddInterfaceLogAsync(interfaceLogInfo);
                                    }
                                    catch (Exception ex)
                                    {
                                        _LogUtil.Error($"异常6：{JsonConvert.SerializeObject(ex)}|{JsonConvert.SerializeObject(interfaceLogInfo)}");
                                    }

                                    continue;
                                }
                                else
                                {
                                    foreach (var ts in taskchecklist)
                                    {
                                        ts.TaskState = EnumTaskState.ManualFinish;
                                        ts.UpdateTime = DateTime.Now;
                                    }
                                    await _workTaskInfoRepository.AsSugarClient().Updateable(taskchecklist).ExecuteCommandAsync();
                                }
                            }
                            #endregion

                            WorkTaskInfo workTaskInfo = new WorkTaskInfo();
                            workTaskInfo.ID = _Snowflake.GetId();
                            workTaskInfo.PalletCode = temp.PalletCode;
                            workTaskInfo.Priority = temp.Priority;
                            workTaskInfo.TaskCode = Convert.ToInt32(temp.TaskCode.ToString().Substring(6, 8));
                            workTaskInfo.TaskProcessState = EnumTaskProcessState.Initial;
                            workTaskInfo.TaskState = EnumTaskState.Initial;
                            workTaskInfo.TaskType = (EnumTaskType)temp.TaskType;
                            workTaskInfo.SaveTime = DateTime.Now;
                            workTaskInfo.UpdateTime = DateTime.Now;
                            workTaskInfo.WmsTaskCode = temp.TaskCode;
                            workTaskInfo.DependWmsTaskCode = temp.DependWMSTaskCode;
                            workTaskInfo.WmsFromStation = temp.FromStation;//WMS起始工位
                            workTaskInfo.WmsToStation = temp.ToStation; //WMS目标工位
                            workTaskInfo.WmsFromPosition = temp.StartPosition;//WMS起始位置
                            workTaskInfo.WmsToPosition = temp.EndPosition;//WMS目标位置
                            var routeInfo = routeInfos.FirstOrDefault(it => it.FromStation == temp.FromStation && it.ToStation == temp.ToStation);
                            if (routeInfo == null)
                            {
                                interfaceLogInfo.Description = $"WCS路径{temp.FromStation}到{temp.ToStation}没有配置";
                                await _IIterfaceLogInfoService.AddInterfaceLogAsync(interfaceLogInfo);
                                continue;
                                //throw new Exception($"WCS路径{temp.FromStation}到{ temp.ToStation}没有配置");
                            }
                            workTaskInfo.RouteID = routeInfo.ID;
                            var routrdetailinfo = routrdetailinfos.FirstOrDefault(it => it.RouteID == workTaskInfo.RouteID && it.IsStart == true);
                            if (routrdetailinfo == null)
                            {
                                interfaceLogInfo.Description = $"WCS路径Id: {workTaskInfo.RouteID}没有配置起点数据";
                                await _IIterfaceLogInfoService.AddInterfaceLogAsync(interfaceLogInfo);
                                //throw new Exception($"WCS路径Id: { workTaskInfo.RouteID }没有配置起点数据");
                                continue;
                            }
                            workTaskInfo.CurrentRounteDetailID = routrdetailinfo.ID;
                            workTaskInfo.CurrentDetailTaskState = EnumDetailTaskState.Init;
                            workTaskInfo.CurrentDispatchType = routrdetailinfo.DispatchType;
                            //消防任务 设置调度类型为消防
                            if (workTaskInfo.Priority == 2)
                            {
                                workTaskInfo.CurrentDispatchType = EnumDispatchType.SC_Fire;
                            }
                            if (workTaskInfo.CurrentDispatchType == EnumDispatchType.SC_DOWN)
                            {
                                workTaskInfo.CurrentFromEquipment = routrdetailinfo.FromEquipment;
                                workTaskInfo.CurrentFromCargo = temp.StartPosition.ToString();
                                workTaskInfo.CurrentToEquipment = routrdetailinfo.ToEquipment;//temp.EndPosition;
                                workTaskInfo.CurrentToCargo = routrdetailinfo.ToCargo;
                                workTaskInfo.CurrentCreateTime = DateTime.Now;
                                workTaskInfo.CurrentUpdateTime = new DateTime(1900, 1, 1);
                            }
                            // 移库和消防调度  WMS发过来的目标货位为真实位置
                            else if (workTaskInfo.CurrentDispatchType == EnumDispatchType.SC_MOVE || workTaskInfo.CurrentDispatchType == EnumDispatchType.SC_Fire)
                            {
                                workTaskInfo.CurrentFromEquipment = routrdetailinfo.FromEquipment;//起始设备
                                workTaskInfo.CurrentFromCargo = temp.StartPosition.ToString();//起始货位
                                workTaskInfo.CurrentToEquipment = routrdetailinfo.ToEquipment;//目标设备
                                workTaskInfo.CurrentToCargo = temp.EndPosition;//目标货位
                                workTaskInfo.CurrentCreateTime = DateTime.Now;
                                workTaskInfo.CurrentUpdateTime = new DateTime(1900, 1, 1);
                            }
                            else
                            {
                                interfaceLogInfo.Description = $"WCS路径Id: {workTaskInfo.RouteID}路径类型配置异常";
                                await _IIterfaceLogInfoService.AddInterfaceLogAsync(interfaceLogInfo);
                                //throw new Exception($"WCS路径Id: { workTaskInfo.RouteID }路径类型配置异常");
                                continue;
                            }
                            workTaskInfo.UploadWmsState = EnumUploadWmsState.Init;
                            workTaskInfo.UploadWmsTime = DateTime.Now;

                            await _workTaskInfoRepository.InsertAsync(workTaskInfo);

                            #region 上报WMS获取任务成功
                            try
                            {
                                bool flag = await WCSMessageWithWMSApi.WCSUpdateWMStaskStateAndProcessTaskStateAsync(temp.TaskCode, 1, null);
                                if (flag)
                                {
                                    workTaskInfo.UploadWmsState = EnumUploadWmsState.Succeed;
                                    workTaskInfo.UploadWmsTime = DateTime.Now;
                                    interfaceLogInfo.Description = $"WMS 作业号{temp.TaskCode} 已更新";
                                    await _IIterfaceLogInfoService.AddInterfaceLogAsync(interfaceLogInfo);
                                }
                            }
                            catch (Exception ex)
                            {
                                interfaceLogInfo.Description = $"异常:{ex}";
                                await _IIterfaceLogInfoService.AddInterfaceLogAsync(interfaceLogInfo);
                                workTaskInfo.UploadWmsState = EnumUploadWmsState.Failed;
                                workTaskInfo.UploadWmsTime = DateTime.Now;
                            }
                            #endregion

                            //查询重复任务 
                            var taskList = await _workTaskInfoRepository.AsSugarClient().Queryable<WorkTaskInfo>()
                                .Where(t => t.PalletCode == workTaskInfo.PalletCode
                                            && t.TaskState == workTaskInfo.TaskState
                                            && t.RouteID == workTaskInfo.RouteID
                                            && t.CurrentRounteDetailID == workTaskInfo.CurrentRounteDetailID)
                                .ToListAsync();
                            //两条相同任务以上就只保留一条
                            if (taskList.Count > 1)
                            {
                                var tempTaskList = taskList.Remove(taskList[0]);
                                if (tempTaskList)
                                {
                                    await _workTaskInfoRepository.AsSugarClient().Deleteable(taskList).ExecuteCommandAsync();
                                    _LogUtil.Debug($"删除重复任务数： {taskList.Count}, 任务号：{workTaskInfo.WmsTaskCode}");
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        interfaceLogInfo.Description = $"异常:{ex}";
                        await _IIterfaceLogInfoService.AddInterfaceLogAsync(interfaceLogInfo);
                        //_LogUtil.Error(ex.ToString());
                    }                    
                }
            }
            catch (Exception ex)
            {
                var endtime = DateTime.Now.ToString("G");
                _LogUtil.Info($"http请求时间：{starttime}，{endtime}");
                interfaceLogInfo.Description = $"异常:{ex}";
                await _IIterfaceLogInfoService.AddInterfaceLogAsync(interfaceLogInfo);
            }
            finally
            {
                //lock_task.Release();
                _LogUtil.Info("获取WMS任务结束>>>>>>>>>>>>>");
            }

            //不要抛异常到IIS或hangfire
            //WMS 下发手动完成和取消的作业 TODO 瑞浦二期68项目没有此业务 暂时不用

        }


        /// <summary>
        /// 定时获取堆垛机初始任务
        /// </summary>
        public async Task GetInitWorkTaskToMemory()
        {
            ////正在更新数据直接返回
            //if (GlobalResource.TaskTableUpdateCount <= 0)
            //{
            //    return;
            //}
            GlobalResource.CurrentSCWorkTaskInfoList = await _workTaskInfoRepository.AsSugarClient()
               .Queryable<WorkTaskInfo>()
               .Where(it => (it.TaskState == EnumTaskState.Initial || it.TaskState == EnumTaskState.Executing) && it.CurrentDetailTaskState == EnumDetailTaskState.Init && (it.CurrentDispatchType == EnumDispatchType.SC_MOVE || it.CurrentDispatchType == EnumDispatchType.SC_UP || it.CurrentDispatchType == EnumDispatchType.SC_DOWN))
               .Select(wti => new WCSWorkTaskInfoDto()
               {
                   ID = wti.ID,
                   RouteID = wti.RouteID,
                   Priority = wti.Priority,
                   PalletCode = wti.PalletCode,
                   TaskCode = wti.TaskCode,
                   TaskProcessState = wti.TaskProcessState,
                   TaskState = wti.TaskState,
                   TaskType = wti.TaskType,
                   SaveTime = wti.SaveTime,
                   UpdateTime = wti.UpdateTime,
                   WmsTaskCode = wti.WmsTaskCode,
                   DependWmsTaskCode = wti.DependWmsTaskCode,
                   WmsFromStation = wti.WmsFromStation,
                   WmsFromPosition = wti.WmsFromPosition,
                   WmsToStation = wti.WmsToStation,
                   WmsToPosition = wti.WmsToPosition,
                   CurrentRounteDetailID = wti.CurrentRounteDetailID,
                   CurrentDetailTaskState = wti.CurrentDetailTaskState,
                   CurrentDispatchType = wti.CurrentDispatchType,
                   CurrentFromEquipment = wti.CurrentFromEquipment,
                   CurrentFromCargo = wti.CurrentFromCargo,
                   CurrentToEquipment = wti.CurrentToEquipment,
                   CurrentToCargo = wti.CurrentToCargo,
                   CurrentCreateTime = wti.CurrentCreateTime,
                   CurrentUpdateTime = wti.CurrentUpdateTime
               })
                .ToListAsync(); 
            //lock (_lockTask)
            //{
            //    GlobalResource.CurrentSCWorkTaskInfoList = taskInfos;
            //}
            //Interlocked.Exchange(ref GlobalResource.TaskTableUpdateCount, 0);
        }


        /// <summary>
        /// 获取符合条件的堆垛机任务
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public IEnumerable<WCSWorkTaskInfoDto> GetScWorkTaskInfo(Func<WCSWorkTaskInfoDto, bool> predicate)
        {
            //if (GlobalResource.TaskTableUpdateCount > 0)
            //{
            //    await GetInitWorkTaskToMemory();
            //}
            return GlobalResource.CurrentSCWorkTaskInfoList.Where(predicate);
        }

    }
}
